#在Backtrader中实现RSI（Relative Strength Index，相对强弱指数）策略，主要依据RSI指标的超买和超卖区域来生成买卖信号。一般而言，当RSI低于某个阈值（如30），被视为超卖，可能是买入时机；而当RSI高于某个阈值（如70），则被视为超买，可能是卖出时机。以下是具体的实现示例：
import backtrader as bt

from strategy.utils.BaoStockPandasData import BaoStockPandasData
from utils.DataSource import get_stock_data2

class RSIStrategy(bt.Strategy):
    params = (
        ('rsi_period', 14),  # RSI计算周期
        ('oversold_rsi', 30),  # 超卖阈值
        ('overbought_rsi', 70),  # 超买阈值
        ('order_percentage', 0.95),  # 交易资金占总资金的百分比
    )

    def __init__(self):
        self.data_close = self.datas[0].close
        self.order = None
        self.rsi = bt.indicators.RSI_Safe(self.data.close, period=self.params.rsi_period)

    def next(self):
        if self.order:
            return  # 如果有订单在执行，则不执行新的买卖操作

        # 当RSI低于超卖阈值且无持仓，视为买入信号
        if self.rsi[0] < self.params.oversold_rsi and not self.position:
            amount_to_invest = (self.params.order_percentage * self.broker.cash) / self.data_close[0]
            self.buy(size=amount_to_invest)
            self.log(f"BUY EXECUTED --- Price: {self.data_close[0]}, RSI: {self.rsi[0]}")

        # 当RSI高于超买阈值且有持仓，视为卖出信号
        elif self.rsi[0] > self.params.overbought_rsi and self.position:
            self.sell()
            self.log(f"SELL EXECUTED --- Price: {self.data_close[0]}, RSI: {self.rsi[0]}")

    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            return  # 订单状态未最终确定，等待

        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f"BUY EXECUTED --- Price: {order.executed.price}, Cost: {order.executed.value}, Commission: {order.executed.comm}")
            else:  # Sell
                self.log(f"SELL EXECUTED --- Price: {order.executed.price}, Size: {order.executed.size}, Commission: {order.executed.comm}")

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        self.order = None

# 回测设置示例
if __name__ == '__main__':
    cerebro = bt.Cerebro()

    # 假设已经通过某种方式（如Yahoo Finance）获取了数据
    df = get_stock_data2("sh.603057", "2020-01-01", "2024-09-26")
    data = BaoStockPandasData(dataname=df)
    cerebro.adddata(data)

    cerebro.addstrategy(RSIStrategy, rsi_period=14, oversold_rsi=30, overbought_rsi=70)

    cerebro.broker.setcash(100000.0)
    cerebro.broker.set_coc(True)  # 现金交易模式

    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    cerebro.run()
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
#这个策略中，我们使用了bt.indicators.RSI_Safe来计算RSI指标，并根据RSI值与预设的超买和超卖阈值来决定买入或卖出。用户可以根据市场情况和个人偏好调整RSI的周期和超买超卖阈值。